﻿//-----------------------------------------------------------------------
// <copyright company="Microsoft Corporation">
//     Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace Microsoft.DevDiv.Wpf.Samples
{
    using System;
    using System.Windows;
    using System.Windows.Threading;

    /// <summary>
    /// IProvideValueTargetSetter implementation for DependencyObject DependencyProperty pairs
    /// </summary>
    public sealed class DependencyPropertyProvideValueTargetSetter<T> : IProvideValueTargetSetter<T>
    {
        public DependencyPropertyProvideValueTargetSetter(DependencyObject targetObject, DependencyProperty targetProperty)
        {
            if (targetObject == null)
            {
                throw new ArgumentNullException("targetObject");
            }

            if (targetProperty == null)
            {
                throw new ArgumentNullException("targetProperty");
            }

            this.targetObject = targetObject;
            this.targetProperty = targetProperty;
        }

        public void SetValue(T value)
        {
            if (this.targetObject == null || this.targetProperty == null)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }

            // Marshal the call back to the UI thread
            this.targetObject.Dispatcher.Invoke(
                DispatcherPriority.Normal,
                (DispatcherOperationCallback)this.SetValueCallback,
                value);
        }

        public void Dispose()
        {
            GC.SuppressFinalize(this);
            this.targetObject = null;
            this.targetProperty = null;
        }

        private object SetValueCallback(object arg)
        {
            this.targetObject.SetValue(this.targetProperty, arg);
            return null;
        }

        private DependencyObject targetObject;
        private DependencyProperty targetProperty;
    }
}
